package com.atguigu.gulimall.web;

import com.atguigu.common.vo.MemberRespVo;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.gulimall.product.vo.Catelog2Vo;
import com.fasterxml.jackson.core.SerializableString;
import org.redisson.api.*;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
public class IndexController {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private CategoryService categoryService;

    @GetMapping({"/","/index.html"})
    public String indexPage(Model model, HttpSession session){



        //TODO 1.查出我们所有的一级分类，并在页面进行显示
        List<CategoryEntity> categoryEntities = categoryService.getLevelFirstCategories();

        model.addAttribute("categories",categoryEntities);
        //springboot自动帮助你利用视图解析器添加前后缀：  classpath:/templates/   +“”+   .html
        return "index";
    }

    //处理二三级分类信息的处理逻辑
    //index/catalog.json
    @GetMapping("/index/catalog.json")
    @ResponseBody
    public Map<String, List<Catelog2Vo>> getCatalogJson(){
        Map<String, List<Catelog2Vo>> map = categoryService.getCatalogJson();
        return map;
    }

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        //首先演示Redisson所提供的可重入锁功能
        //1.获取一把锁，只要锁的名字一样，就是同一把锁
        RLock lock = redissonClient.getLock("my-lock");

        //2.加锁
        lock.lock();

//        lock.lock(10, TimeUnit.SECONDS);
        try{
            System.out.println("加锁成功，执行业务。。。");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            //3.解锁,无论代码出不出现问题，都要进行解锁，否则会出现死锁
            lock.unlock();
            System.out.println("释放锁。。。。。");
        }
        return "hello";
    }


    @ResponseBody
    @RequestMapping("/write")
    public String writeValue(){
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        String s = UUID.randomUUID().toString();
        RLock rLock = readWriteLock.writeLock();
        System.out.println("获取了写锁");
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        try {
            Thread.sleep(20000);
            System.out.println("执行业务中。。。。写数据为："+s);
            ops.set("writeValue",s);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
            System.out.println("释放了写锁。。");
        }
        return s;
    }

    @ResponseBody
    @RequestMapping("/read")
    public String readValue(){
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        RLock rLock = readWriteLock.readLock();
        System.out.println("获取了读锁");
        String writeValue = "";
        try {
            writeValue = ops.get("writeValue");
//            System.out.println("读数据为："+writeValue);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
            System.out.println("释放了读锁。。。");
        }
        return writeValue;
    }


    @ResponseBody
    @RequestMapping("/park")
    public String park() throws InterruptedException {
        RSemaphore park = redissonClient.getSemaphore("park");
        park.acquire();
        return "ok";
    }


    @ResponseBody
    @RequestMapping("/go")
    public String go(){
        RSemaphore park = redissonClient.getSemaphore("park");
        park.release();

        return "go";
    }

    /**
     * 五个班级都走了才会锁大门放假
     * @return
     * @throws InterruptedException
     */
    @ResponseBody
    @RequestMapping("/lockDoor")
    public String lockDoor() throws InterruptedException {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.trySetCount(5);
        door.await();
        return "放假了。。。";
    }

    @ResponseBody
    @RequestMapping("/gogogo/{id}")
    public String gogogo(@PathVariable("id") Long id){
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();

        return id+"班的人都走了";
    }
}
